package org.jsets.fastboot.oss.service.impl;

import org.jsets.fastboot.oss.mapper.BucketMapper;
import org.jsets.fastboot.oss.model.constant.Buckets;
import org.jsets.fastboot.oss.model.dto.BucketQuery;
import org.jsets.fastboot.oss.model.dto.StorageQuery;
import org.jsets.fastboot.oss.model.entity.Bucket;
import org.jsets.fastboot.oss.model.entity.Storage;
import org.jsets.fastboot.oss.service.IBucketService;
import org.jsets.fastboot.oss.service.IStorageConfigService;
import org.jsets.fastboot.oss.service.IStorageEngineService;
import org.jsets.fastboot.persistent.support.LambdaQuerier;
import org.jsets.fastboot.persistent.support.LambdaUpdater;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.List;

@Service
public class BucketService extends ServiceImpl<BucketMapper, Bucket> implements IBucketService {

	@Autowired
	private IStorageConfigService configService;

	@Override
	public void initialize() {
		List<Storage> configs = this.configService.selectList(new StorageQuery());
		for(Storage config : configs) {
			if(this.configService.containEngineService(config.getId())) {
				IStorageEngineService engineService = this.configService.getOrCreateEngineService(config.getId());
				Bucket defaultBucket = this.getByName(Buckets.DEFAULT);
				if(null == defaultBucket) {
					defaultBucket = new Bucket();
					defaultBucket.setName(Buckets.DEFAULT);
					defaultBucket.setNoticeable(false);
					defaultBucket.setStorageId(config.getId());
					this.insertBucket(defaultBucket);
				}
				
				List<String> bucketNames = engineService.listBuckets();
				for(String bucketName:bucketNames) {
					Bucket bucket = this.getByName(bucketName);
					if(null==bucket) {
						bucket = new Bucket();
						bucket.setName(bucketName);
						bucket.setNoticeable(false);
						bucket.setStorageId(config.getId());
						this.insertBucket(bucket);
					}
				}
			}
		}
	}
	
	@Override
	@Transactional
	public void insertBucket(Bucket entity) {
		boolean succeed = this.save(entity);
		if (succeed) {
			this.configService.getOrCreateEngineService(entity.getStorageId()).makeBucket(entity.getName());
		}
	}

	@Override
	public void updateBucket(Bucket entity) {
		this.updateById(entity);
	}

	@Override
	@Transactional
	public void removeBucket(Bucket entity) {
		boolean succeed = this.removeById(entity.getId());
		if (succeed) {
			this.configService.getOrCreateEngineService(entity.getStorageId()).removeBucket(entity.getName());
		}
	}

	@Override
	public Bucket getByName(String name) {
		return LambdaQuerier
				.build(Bucket.class)
				.setBaseMapper(this.getBaseMapper())
				.eq(Bucket::getName, name)
				.selectOne();
	}
	
	@Override
	public int selectCountByStorage(String storageId) {
		return LambdaQuerier
				.build(Bucket.class)
				.setBaseMapper(this.getBaseMapper())
				.eq(Bucket::getStorageId, storageId)
				.selectCount();
	}

	@Override
	public Page<Bucket> selectPage(BucketQuery criteria) {
		Page<Bucket> page = new Page<Bucket>();
		page.setCurrent(criteria.getCurrent());
		page.setSize(criteria.getSize());
		List<Bucket> list = this.getBaseMapper().selectPage(page, criteria);
		page.setRecords(list);
		return page;
	}
	
	@Override
	public List<Bucket> selectList(BucketQuery criteria) {
		return LambdaQuerier
				.build(Bucket.class)
				.setBaseMapper(this.getBaseMapper())
				.eqIfNecessary(Bucket::getName, criteria.getName())
				.orderByDesc(Bucket::getCreateTime)
				.selectList();
	}
}